//////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVABLE_H_
#define _OBSERVABLE_H_

//////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVER_H_
#include "observer.h"
#endif

//////////////////////////////////////////////////////////////////////////



/** This class implements Observer design pattern
*
*   Usage: 
*   1. Create a subclass of Observable;
*   2. To notify observers call NotifyObservers() 
*      with desired event as parameter;
*
*  @author   Roman Pasechnik
*  @since    Aug 04th, 2009
*  @updated  Jan 22th, 2010
*/
class Observable
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////


    /** Destructor */
    virtual ~Observable()
    {
    }


//////////////////////////////////////////////////////////////////////////


    /** Adds new observer */
    void AddObserver( Observer* _observer )
    {
        // Add observer to collection
        m_Observers.insert(_observer);
    }


//////////////////////////////////////////////////////////////////////////


    /** Removes existing observer */
    void RemoveObserver( Observer* _observer )
    {
        // Remove observer from collection
        m_Observers.erase(_observer);
    }


//////////////////////////////////////////////////////////////////////////


    /** Notifies all observers about event */
    void NotifyObservers( Observer::Event _event )
    {
        // For all observers
        Observers::iterator it = m_Observers.begin();
        while ( it != m_Observers.end() )
        {
            Observer* observer = *it;
            if (observer)
            {
                // If observer triggers on this event
                if ( observer->IsEventToObserve(_event) )
                    // Call event handler
                    observer->OnEvent(_event, this);
            }

            // Next observer
            ++it;
        }
    }


//////////////////////////////////////////////////////////////////////////

private:

//////////////////////////////////////////////////////////////////////////


    /** [Utility type]: a set of Observer pointers */
    typedef std::set<Observer*> Observers;


    /** All observers, that are observing this object */
    Observers m_Observers;


//////////////////////////////////////////////////////////////////////////
};


//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////

